# src/llm_clients/deepseek_client.py
import os
import logging
from typing import List, Dict, Any, AsyncGenerator, Optional

from openai import AsyncOpenAI # 使用 AsyncOpenAI 进行异步操作
from openai import APIConnectionError, APIStatusError # Import specific exceptions for better handling

logger = logging.getLogger(__name__)

# 从环境变量获取 DeepSeek API Key
DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY")
# DeepSeek API 的基础 URL，根据您的示例
DEEPSEEK_BASE_URL = "https://api.deepseek.com"

if not DEEPSEEK_API_KEY:
    logger.warning(
        "DEEPSEEK_API_KEY 环境变量未设置。DeepSeek 客户端可能无法正常工作。"
        "请确保在使用前设置此环境变量。"
    )

class DeepSeekLLMClient:
    """
    一个用于与 DeepSeek API 进行异步交互的客户端。
    它使用与 OpenAI SDK 兼容的接口。
    """
    def __init__(self, api_key: str = DEEPSEEK_API_KEY, base_url: str = DEEPSEEK_BASE_URL):
        if not api_key:
            # 如果在实例化时仍未提供 API 密钥，则引发错误
            raise ValueError(
                "DeepSeek API 密钥未配置。请设置 DEEPSEEK_API_KEY 环境变量或在实例化时提供 api_key。"
            )
        self.client = AsyncOpenAI(api_key=api_key, base_url=base_url)
        self.model_name = "deepseek-chat" # 默认模型，可以根据需要更改或作为参数传递

    async def chat_stream(
        self,
        messages: List[Dict[str, str]],
        model: Optional[str] = None
    ) -> AsyncGenerator[Dict[str, Any], None]:
        """
        向 DeepSeek API 发送聊天请求并以流式方式获取响应。

        参数:
            messages: 一个消息对象列表，每个对象包含 "role" 和 "content"。
                      例如: [{"role": "user", "content": "你好"}]
            model: 要使用的模型名称，例如 "deepseek-chat"。如果为 None，则使用客户端的默认模型。

        返回:
            一个异步生成器，逐块产生包含事件和数据的字典。
            例如: {"event": "text", "data": "你好"}
                  {"event": "error", "data": "错误信息"}
        """
        selected_model = model if model else self.model_name

        if not self.client:
            logger.error("DeepSeek 客户端未正确初始化 (可能由于缺少 API 密钥)。")
            yield {"event": "error", "data": "DeepSeek 客户端未初始化。"}
            return

        try:
            logger.info(f"向 DeepSeek 模型 '{selected_model}' 发送包含 {len(messages)} 条消息的请求。")
            # logger.debug(f"发送的消息内容: {messages}") # 敏感信息，仅在调试时开启

            response_stream = await self.client.chat.completions.create(
                model=selected_model,
                messages=messages,
                stream=True,
                # 可以根据需要添加其他参数，如 temperature, max_tokens 等
                # temperature=0.7,
                # max_tokens=1024,
            )

            async for chunk in response_stream:
                if chunk.choices:
                    delta = chunk.choices[0].delta
                    chunk_content = delta.content
                    
                    if chunk_content is not None:
                        yield {"event": "text", "data": chunk_content}
                
                # 检查是否有完成原因，可以用于判断流是否正常结束
                # finish_reason = chunk.choices[0].finish_reason
                # if finish_reason:
                #    logger.info(f"DeepSeek stream finished with reason: {finish_reason}")
                #    yield {"event": "stream_end", "data": {"finish_reason": finish_reason}}


        except APIConnectionError as e:
            logger.error(f"无法连接到 DeepSeek API: {e}")
            yield {"event": "error", "data": f"无法连接到 DeepSeek API: {str(e)}"}
        except APIStatusError as e:
            logger.error(f"DeepSeek API 返回错误状态: {e.status_code} - {e.response}")
            yield {"event": "error", "data": f"DeepSeek API 错误: {e.status_code} - {e.message}"}
        except Exception as e:
            logger.exception(f"调用 DeepSeek API 时发生未知错误: {e}")
            yield {"event": "error", "data": f"与 DeepSeek API 通信时发生未知错误: {str(e)}"}
